package com.hu.article.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hu.article.feign.UserClient;
import com.hu.article.service.IBlogService;
import com.hu.article.service.ICommentService;
import com.hu.common.controller.BaseController;
import com.hu.common.pojo.Comment;
import com.hu.common.pojo.User;
import com.hu.common.pojo.dto.Response;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.server.ServerWebExchange;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 留言表 前端控制器
 * </p>
 *
 * @author hu
 * @since 2023-09-10
 */
@RestController
@RequestMapping("/comment")
public class CommentController extends BaseController {

    @Resource
    private ICommentService commentService;
    @Resource
    private IBlogService blogService;
    @Resource
    private UserClient userClient;

    private final String now = DateUtil.now();

    // 新增或者更新
    @PostMapping
    public Response save(@RequestBody Comment comment, ServerWebExchange exchange) {
        // 新增评论
        if (comment.getId() == null) {
            HttpHeaders headers = exchange.getRequest().getHeaders();
            List<String> list = headers.get("token");
            String token = list.get(0);
            User user = userClient.getUserByToken(token);
            comment.setUserId(user.getId());
            comment.setTime(DateUtil.now());

            // 回复
            if (comment.getPid() != null) {
                // 如果回复的评论已经有了pid,则设置相同的originId
                // 如果回复的评论没有pid，，则将前端传过来的pid，设置为该条评论的originId
                Integer pid = comment.getPid();
                Comment pComment = commentService.getById(pid);
                if (pComment.getOriginId() != null) {
                    comment.setOriginId(pComment.getOriginId());
                }else {
                    comment.setOriginId(comment.getPid());
                }
            }
        }
        Integer blogId = comment.getBlogId();
        blogService.addCommentCount(blogId);
        commentService.saveOrUpdate(comment);
        return success();
    }

    @DeleteMapping("/{id}")
    public Response delete(@PathVariable Integer id) {
        Integer blogIdByCommentId = commentService.getBlogIdByCommentId(id);
        int count = commentService.countPid(id) + 1;
        blogService.reduceCommentCount(blogIdByCommentId,count);
        // 先删除本条评论
        commentService.removeById(id);
        // 如果评论下面有回复，删除评论的同时删除所有的回复
        // 删除pid等于传入id的记录
        QueryWrapper<Comment> pidQueryWrapper = new QueryWrapper<>();
        pidQueryWrapper.eq("pid", id);
        commentService.remove(pidQueryWrapper);
        // 删除originId等于传入id的记录
        QueryWrapper<Comment> originIdQueryWrapper = new QueryWrapper<>();
        originIdQueryWrapper.eq("origin_id", id);
        commentService.remove(originIdQueryWrapper);
        return success();
    }

    @PostMapping("/del/batch")
    public Response deleteBatch(@RequestBody List<Integer> ids) {
        commentService.removeByIds(ids);
        return success();
    }

    @GetMapping
    public Response findAll() {
        return success(commentService.list());
    }

    @GetMapping("/commentDetail/{blogId}")
    public Response findCommentTree(@PathVariable Integer blogId) {
        // 查询所有的评论和回复数据
        List<Comment> commentList = commentService.findCommentDetail(blogId);
        // 先查出评论，不包括回复
        List<Comment> originList = commentList.stream().filter(comment -> comment.getOriginId() == null).collect(Collectors.toList());

        // 将二三级评论挂在回复下面
        for (Comment origin : originList) {
            List<Comment> replyList = commentList.stream().filter(comment -> origin.getId().equals(comment.getOriginId())).collect(Collectors.toList());
            origin.setChildren(replyList);
        }
        return success(originList);
    }

    @GetMapping("/page")
    public Response findPage(@RequestParam(defaultValue = "") String name,
                           @RequestParam Integer pageNum,
                           @RequestParam Integer pageSize) {
        QueryWrapper<Comment> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("id");
        if (!"".equals(name)) {
            queryWrapper.like("name", name);
        }
        return success(commentService.page(new Page<>(pageNum, pageSize), queryWrapper));
    }

    /**
    * 导出接口
    */
    @GetMapping("/export")
    public void export(HttpServletResponse response) throws Exception {
        // 从数据库查询出所有的数据
        List<Comment> list = commentService.list();
        // 在内存操作，写出到浏览器
        ExcelWriter writer = ExcelUtil.getWriter(true);

        // 一次性写出list内的对象到excel，使用默认样式，强制输出标题
        writer.write(list, true);

        // 设置浏览器响应的格式
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        String fileName = URLEncoder.encode("Comment信息表", "UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");

        ServletOutputStream out = response.getOutputStream();
        writer.flush(out, true);
        out.close();
        writer.close();

        }

    /**
     * excel 导入
     * @param file
     * @throws Exception
     */
    @PostMapping("/import")
    public Response imp(MultipartFile file) throws Exception {
        InputStream inputStream = file.getInputStream();
        ExcelReader reader = ExcelUtil.getReader(inputStream);
        // 通过 javabean的方式读取Excel内的对象，但是要求表头必须是英文，跟javabean的属性要对应起来
        List<Comment> list = reader.readAll(Comment.class);

        commentService.saveBatch(list);
        return success();
    }
}

